/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package votingkeypair;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 *
 * @author student
 */
public class CypherModel {
    
         byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };
    
         
       private byte[] encrypt(String text, String password) throws BadPaddingException{
        try {
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
            PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 0x1);
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey,pbeParamSpec);
            return pbeCipher.doFinal(text.getBytes());
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidAlgorithmParameterException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeySpecException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        }
            return null;
       }
        
        public boolean write(String text, String fileName, String password) throws FileNotFoundException, IOException, BadPaddingException{
           
            byte[] data = encrypt(text,password);
           
            if(data == null) return false;
            OutputStream out = new FileOutputStream(fileName);
            out.write(data);
            out.close();
            return true;
 
       }
        
       public byte[] encrypt(byte[] data, String password) throws BadPaddingException{
            try {
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
            PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 0x1);
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey,pbeParamSpec);
            return pbeCipher.doFinal(data);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidAlgorithmParameterException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeySpecException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
        }
            return null;
       }
        
        public String decrypt(byte[] encryptedText, String password) throws BadPaddingException{
                try {
                    PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
                     SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
                     SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
                     PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 0x1);

                     Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
                     pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey,pbeParamSpec);
                     byte[] result = pbeCipher.doFinal(encryptedText);
                     return new String(result);
                } catch (InvalidKeyException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvalidAlgorithmParameterException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalBlockSizeException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                
                } catch (NoSuchPaddingException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvalidKeySpecException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (NoSuchAlgorithmException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
        }
        
       
        
        public byte[] decryptToBytes(byte[] encryptedText, String password) throws BadPaddingException{
                try {
                    PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
                     SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
                     SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
                     PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 0x1);

                     Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
                     pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey,pbeParamSpec);
                     byte[] result = pbeCipher.doFinal(encryptedText);
                     return result;
                } catch (InvalidKeyException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvalidAlgorithmParameterException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalBlockSizeException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                
                } catch (NoSuchPaddingException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvalidKeySpecException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (NoSuchAlgorithmException ex) {
                    Logger.getLogger(CypherModel.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
        }
        public String load(String fileName,String password) throws FileNotFoundException, IOException, BadPaddingException{
            //ByteArrayOutputStream data = new ByteArrayOutputStream();
            InputStream in = new FileInputStream(fileName);
            byte[] data = new byte[ (int)(new File(fileName)).length()];
            in.read(data);
            in.close();
            return decrypt(data,password);
        }

    public boolean write(String text, File selectedFile, String password) throws BadPaddingException, FileNotFoundException, IOException {
          byte[] data = encrypt(text,password);
           
            if(data == null) return false;
            OutputStream out = new FileOutputStream(selectedFile);
            out.write(data);
            out.close();
            return true;
    }

    public String load(File selectedFile, String password) throws FileNotFoundException, IOException, BadPaddingException {
            InputStream in = new FileInputStream(selectedFile);
            byte[] data = new byte[ (int)(selectedFile).length()];
            in.read(data);
            in.close();
            return decrypt(data,password);
    }
}
